package com.qiuling.iot.shiro;

import com.alibaba.fastjson.JSON;
import com.qiuling.iot.Exception.BusinessException;
import com.qiuling.iot.Exception.code.BaseResponseCode;
import com.qiuling.iot.constants.Constant;
import com.qiuling.iot.utils.DataResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.web.filter.AccessControlFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Map;


/**
 * @Author：zhangqiang
 * @Description：
 * @Date：Created in 1:47 2020/2/10
 * @Modified By：
 */
@Slf4j
public class CustomAccessControlerFilter extends AccessControlFilter {

    public static List<Map<String, Deque<Serializable>>> list = new ArrayList<>();

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest,
                                      ServletResponse servletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest,
                                     ServletResponse servletResponse) throws Exception {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        log.info(request.getMethod());
        log.info(request.getRequestURL().toString());

        //判断客户端是否携带accessToken
        try {
            String accessToken = request.getHeader(Constant.ACCESS_TOKEN);
            if (StringUtils.isEmpty(accessToken)) {
                throw new BusinessException(BaseResponseCode.TOKEN_NOT_NULL);
            }
            /**
             * 授权token
             */
            CustomUsernamePasswordToken customUsernamePasswordToken = new CustomUsernamePasswordToken(accessToken);
            getSubject(servletRequest, servletResponse).login(customUsernamePasswordToken);

        } catch (BusinessException e) {
            customRsponse(e.getCode(), e.getDefaultMessage(), servletResponse);
            return false;
        } catch (AuthenticationException e) {
            if (e.getCause() instanceof BusinessException) {
                BusinessException exception = (BusinessException) e.getCause();
                customRsponse(exception.getCode(), exception.getDefaultMessage(), servletResponse);
            } else {
                customRsponse(BaseResponseCode.SHIRO_AUTHENTICATION_ERROR.getCode(),
                        BaseResponseCode.SHIRO_AUTHENTICATION_ERROR.getMsg(), servletResponse);
            }
            return false;
        }
        return true;
    }

    /**
     * @param code
     * @param msg
     * @param response
     * @return void
     * @description 自定义错误响应
     * </br>
     * @author zhangqiang
     * @date 1:50 2020/2/10
     */
    private void customRsponse(int code, String msg, ServletResponse response) {
        // 自定义异常的类，用户返回给客户端相应的JSON格式的信息
        try {
            DataResult result = DataResult.getResult(code, msg);
            response.setContentType("application/json; charset=utf-8");
            response.setCharacterEncoding("UTF-8");
            String userJson = JSON.toJSONString(result);
            OutputStream out = response.getOutputStream();
            out.write(userJson.getBytes("UTF-8"));
            out.flush();
        } catch (IOException e) {
            log.error("eror={}", e);
        }
    }

}
